/* nbd-dev.c */

#include <stdlib.h>
#include <stdio.h>

#include <unistd.h>
#include <fcntl.h>

#include "nbd-dev.h"
#include "dump.h"

/**
 * Open device image.
 */
int nbd_dev_open_image(NBD_DEV *dev, const char *filename)
{
  dev->fd = open(filename, O_RDONLY);
  if (dev->fd < 0)
    return -1;
  return 0;
}

/**
 * Close device.
 */
void nbd_dev_close(NBD_DEV *dev)
{
  close(dev->fd);
  dev->fd = -1;
}

/**
 * Return the device size (in bytes), or -1 on error.
 */
long long nbd_dev_get_size(NBD_DEV *dev)
{
  return lseek(dev->fd, 0ll, SEEK_END);
}

/**
 * Read len bytes of device from the given offset.
 */
int nbd_dev_read_data(NBD_DEV *dev, void *buf, int len, unsigned long long off)
{
  unsigned long long new_off;
  unsigned char *p;
  int done;

  new_off = lseek(dev->fd, off, SEEK_SET);
  if (new_off != off) {
    dump_msg("ERROR: can't lseek() device image\n");
    return -1;
  }

  p = buf;
  done = 0;
  while (done < len) {
    int r = read(dev->fd, p, len - done);
    if (r <= 0) {
      dump_msg("ERROR reading device image\n");
      return -1;
    }
    p += r;
    done += r;
  }
  return done;
}
